package object2D;

import byggeTegner.ByggeTegner;
import byggeTegner.DrawPanel;
import context.*;
import model2D.Model2D;
import object3D.LoftTrapp;

import geometry2D.MetricPoint2D;
import geometry2D.Projection2D;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import org.json.JSONException;
import org.json.JSONObject;

import util.FillStyle;
import util.StrokeStyle;
import util.Util;
import util.Util2;

//***************************************************************************
//*** CLASS: LoftTrappProjection
//***************************************************************************
public class LoftTrappProjection extends BlockProjection implements Context.Constants
{ //private static final boolean DEBUG=true; // Overriding Context.Constants.DEBUG
  static final String TAG="object2D.LoftTrappProjection";
  static final String TYPE="LoftTrapp";

  protected LoftTrapp getLoftTrapp() { return((LoftTrapp)block); }
	
  // *************************************************************************
  // *** CONSTRUCTOR: LoftTrappProjection
  // *************************************************************************
  public LoftTrappProjection(Model2D objectModel,LoftTrapp trapp,int type,int direction,Color color,float opacity)
  throws JSONException
  { super(objectModel,trapp,type,direction,color,opacity); }
  
  public LoftTrappProjection(Model2D objectModel,JSONObject jsonObject) throws JSONException
  { super(objectModel,jsonObject);
    if(DEBUG) Log.d(TAG,"decodeSVG: jsonObject="+jsonObject);
    this.fill=new FillStyle(jsonObject);
    this.stroke=new StrokeStyle(jsonObject);
//    boolean closed=jsonObject.optBoolean("closed",false);
//    JSONArray d=jsonObject.getJSONArray("d");
//    //if(DEBUG) Log.d(TAG,"PathObject.decodeSVG: name="+name+", d="+d);
//    clearPointSet();
//    for(int i=0;i<d.length();i++)
//    { JSONArray p=d.getJSONArray(i);
//      add(new MetricPoint2D(p));
//    }
//    setClosedPath(closed);
  }

  public JSONObject toJSONObject() throws JSONException
  { JSONObject jsonObject=new JSONObject();
    jsonObject.put("type",TYPE);
    jsonObject.put("id",getIdent());
//    jsonObject.put("closed",getClosedPath());  
//    jsonObject.put("d",getD());
    jsonObject.put("fill",fill.encode());
    jsonObject.put("stroke",stroke.encode());
	return(jsonObject);
  }


  // *************************************************************************
  // *** METHOD: paint
  // *************************************************************************
  public void paint(Graphics2D g,DrawPanel drawPanel)
  { Projection2D r=getLoftTrapp().toProjection2D(direction);
    switch(direction)
    { case NORTH: tegnTrapp(direction,g,r,color); break;
      case SOUTH: tegnTrapp(direction,g,r,color); break;
      case EAST: tegnTrapp(direction,g,r,color); break;
      case WEST: tegnTrapp(direction,g,r,color); break;
//      case ABOVE: drawProjectionAbove(g,r,color); break;
//      case BELOW: drawProjectionBelow(g,r,color); break;
//      case VCUT: drawVerticalCut(g,r,color); break;
      case ABOVE: tegnTrappPlan(g,r,color); break;
      default: super.paint(g,drawPanel);
    }  
  }

  private void tegnTrapp(int direction,Graphics2D g,Projection2D r,Color c)
  {
  }

  private void tegnTrappPlan(Graphics2D g,Projection2D r,Color c)
  {
//    Util.fill(g,r,Color.yellow);//c);
	Util.draw(g,r);
    double inntrinn=r.width/8;

    // Tegn trapp
    for(int i=0;i<8;i++)
//    { double x2=r.x+0.20*i;
    { double x2=r.x+i*inntrinn;
      double y1=r.y;
      double y2=r.y+r.height;
      line(g,x2,y1,x2,y2);
    }
    // Tegn pil
    { double x0=r.x+0.30;
      double y=r.y+r.height/2;
      double xE=x0+0.80;
      tegnPil(g,x0,y,xE,y);
    }
  }
  
  private void tegnPil(Graphics2D g,double x1,double y1,double x2,double y2)
  { double dx=(x1-x2)*0.30; // 20% av lengden
    double dy=dx/2*1.5;    
    line(g,x1,y1,x2,y2);
    line(g,x2,y2,x2+dx,y2+dy);
    line(g,x2,y2,x2+dx,y2-dy); 
  }
  
  private void line(Graphics2D g,double x1,double y1,double x2,double y2)
  { Util.draw(g,new Line2D.Double(x1,y1,x2,y2),opacity); }
  
  // ****************************************************************
  // *** INNER CLASS: EditGeneralPanel
  // ****************************************************************
  public JPanel getEditGeneralPanel(String title)
  { return(new EditGeneralPanel(title)); }
  private class EditGeneralPanel extends JPanel
  { static final long serialVersionUID=0; // AD'HOC
    private JTextField identField;
    private JButton strokeButton;
    private JButton fillButton;
      
    public void paint(Graphics g)
    { if(DEBUG) Log.d(TAG,"EditGeneralPanel.paint: ");
      identField.setText(getIdent());
      strokeButton.setBackground(stroke.getColor());
      fillButton.setBackground(fill.getColor());
  	  super.paint(g);  
    }
    	
    public EditGeneralPanel(String title)
    { setBorder(Util2.getTitleBorder(title));
      if(numberOfPoints()==4) // Firkant
      { setPreferredSize(new Dimension(350,120));//140));
        setLayout(new GridLayout(6,2));
      }
      else
      { setPreferredSize(new Dimension(350,120));
        setLayout(new GridLayout(5,2));
      }
      add(new JLabel("       Ident:"));
      identField=new JTextField(getIdent());
      identField.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setIdent(identField.getText()); }
      });
      add(identField);
      fillButton=addEditFillButton(this,true);
      strokeButton=addEditStrokeButton(this,true);
        
      JCheckBox closedBox=new JCheckBox("Closed Path",null,getClosedPath());
      closedBox.addActionListener(new ActionListener()
      { public void actionPerformed(ActionEvent e)
        { setClosedPath(!getClosedPath());
          ByggeTegner.repaint();        	
        }
      });
      add(closedBox);
      add(new JLabel(" ")); // Space only
      
      if(numberOfPoints()==4)
      { JButton parallelogramButton=new JButton("Adjust Parallelogram");
//      parallelogramButton.setBackground(fill.getColor());
        parallelogramButton.addActionListener(new ActionListener()
        { public void actionPerformed(ActionEvent e) { ensureParallelogram(); } });
        add(parallelogramButton);
        
        JButton rectangleButton=new JButton("Adjust Rectangle");
//      rectangleButton.setBackground(fill.getColor());
        rectangleButton.addActionListener(new ActionListener()
        { public void actionPerformed(ActionEvent e) { ensureRectangle(); } });
        add(rectangleButton);
      }
    }
  }
  
  private void ensureParallelogram()
  { if(this.numberOfPoints()==4)
    { MetricPoint2D p0=getMapLocation(0);
      MetricPoint2D p1=getMapLocation(1);
      MetricPoint2D p2=getMapLocation(2);
      MetricPoint2D p3=getMapLocation(3);
      double dx=p1.getX()-p0.getX();
      double dy=p1.getY()-p0.getY();
      p3.setX(p2.getX()-dx);
      p3.setY(p2.getY()-dy);
    }
  }
  
  private void ensureRectangle()
  { if(numberOfPoints()==4)
    { MetricPoint2D p0=getMapLocation(0);
      MetricPoint2D p1=getMapLocation(1);
      MetricPoint2D p2=getMapLocation(2);
      double dx=p1.getX()-p0.getX();
      double dy=p1.getY()-p0.getY();
      double a=p2.getY()-p1.getY();      
      double b=dy/dx*a;
      p2.setX(p1.getX()-b);
      ensureParallelogram();
    }
  }

}